package com.keepers.repair.utils

import android.content.Context
import android.graphics.Bitmap
import android.net.ConnectivityManager
import android.os.Environment
import android.os.Looper
import android.util.Base64
import com.blankj.utilcode.util.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Action
import io.reactivex.functions.Function
import okhttp3.ResponseBody
import java.io.*
import java.text.SimpleDateFormat
import java.util.*


/**
 * 网络是否可用
 *
 * @param context 上下文
 * @return true则网络可用, false则网络不可用
 */
fun isNetworkConnected(): Boolean {
    val manager = Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetworkInfo = manager.activeNetworkInfo
    return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
}

/**
 * 将图片转换成 base64 字符串
 *
 * @param  bm  图片的 Bitmap
 * @return     编码后的字符串
 */
fun encodeBase64Image(bm: Bitmap): String {
    val baos = ByteArrayOutputStream()
    bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    val b = baos.toByteArray()
    return Base64.encodeToString(b, Base64.DEFAULT)
}

/**
 * 将图片转换成 base64 字符串
 *
 * @param path 文件路径
 * @return     编码后的字符串
 */
fun encodeBase64File(path: String): String {
    val file = File(path)
    val inputStream = FileInputStream(file)
    val bytes = ByteArray(inputStream.available())
    inputStream.read(bytes)
    return Base64.encodeToString(bytes, Base64.DEFAULT)
}

/**
 * 将字符串进行 Base64 编码
 *
 * @param str 要编码的字符串
 * @return 编码成功的 Base64
 */
fun encodeBase64(str: String): String {
    return Base64.encodeToString(str.toByteArray(), Base64.DEFAULT)
}

/**
 * 将字符串进行 Base64 解码
 *
 * @param base64 Base64字符串
 * @return 解码的字符串
 */
fun decodeBase64(base64: String): String {
    return String(Base64.decode(base64, Base64.DEFAULT))
}

/**
 * 获取版本信息
 *
 * @param context 上下文环境
 * @return 版本信息
 */
fun getVersion(context: Context): String? {
    return try {
        val packageManager = context.packageManager
        val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
        packageInfo.versionName
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

/**
 * 获取系统图标
 *
 * @param context 上下文环境
 * @return 系统图标资源
 */
fun getIcon(context: Context): Int? {
    return try {
        val packageManager = context.packageManager
        val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
        packageInfo.applicationInfo.icon
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

/**
 * 获取当前时间格式化字符串
 *
 * @return 格式化之后的时间字符串
 */
fun getDateString(): String {
    val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
    return formatter.format(Date())
}

/**
 * 将文件流写入磁盘
 *
 * @param name    文件名
 * @param body    响应体
 * @return 写入是否成功
 */
fun writeToDisk(name: String, body: ResponseBody): File? {
    val file = File("${Environment.getExternalStorageDirectory()}${File.separator}.repaired/voice/$name")
    var inputStream: InputStream? = null
    var outputStream: FileOutputStream? = null
    try {
        inputStream = body.byteStream()
        outputStream = FileOutputStream(file)
        inputStream?.apply {
            val bytes = ByteArray(this.available())
            this.read(bytes)
            outputStream.write(bytes)
            outputStream.flush()
            return file
        }
        return null
    } catch (exception: IOException) {
        exception.printStackTrace()
        return null
    } finally {
        inputStream?.close()
        outputStream?.close()
    }
}

fun <T, K> convertItems(list: List<T>, function: Function<T, K>): List<K> {
    return Observable.fromIterable(list)
            .map(function)
            .toList()
            .blockingGet()
}

/**
 * 安全的线程操作
 */
fun safelyTask(action0: Action): Disposable {
    return if (Looper.myLooper() == Looper.getMainLooper()) {
        Observable.empty<Any>().subscribe { action0.run() }
    } else {
        AndroidSchedulers.mainThread().scheduleDirect {
            try {
                action0.run()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}
